﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Workflow.ComponentModel;
using System.Workflow.Runtime;

namespace EssentialWF.Activities
{
    [Serializable]
    public class Sequence : CompositeActivity
    {
        protected override ActivityExecutionStatus Execute(ActivityExecutionContext executionContext)
        {
            if (this.EnabledActivities.Count == 0)
            {
                return ActivityExecutionStatus.Closed;
            }

            Activity child = this.EnabledActivities[0];
            child.Closed += this.ContinueAt;
            executionContext.ExecuteActivity(child);

            return ActivityExecutionStatus.Executing;
        }

        void ContinueAt(object sender, ActivityExecutionStatusChangedEventArgs e)
        {
            ActivityExecutionContext aec =
                sender as ActivityExecutionContext;

            e.Activity.Closed -= this.ContinueAt;
            int index = this.EnabledActivities.IndexOf(e.Activity);

            if ((index + 1) == this.EnabledActivities.Count)
            {
                aec.CloseActivity();
            }
            else
            {
                Activity child = this.EnabledActivities[index + 1];
                child.Closed += this.ContinueAt;
                aec.ExecuteActivity(child);
            }
        }
    }

    

    [Serializable]
    public class PriorityWriteLine : WriteLine
    {
        public static readonly DependencyProperty PriorityProperty =
            DependencyProperty.Register("Priority",
            typeof(int), typeof(PriorityWriteLine));

        public int Priority
        {
            get
            {
                return (int)GetValue(PriorityProperty);
            }
            set
            {
                SetValue(PriorityProperty, value);
            }
        }
    }

    [Serializable]
    public class WriteLine : Activity
    {
        public static readonly DependencyProperty TextProperty =
            DependencyProperty.Register("Text",
            typeof(string), typeof(WriteLine));

        public string Text
        {
            get
            {
                return (string)GetValue(TextProperty);
            }
            set
            {
                SetValue(TextProperty, value);
            }
        }

        //private string text = DateTime.Now.ToLongDateString();
        //public string Text
        //{
        //    get
        //    {
        //        return text;
        //    }
        //    set
        //    {
        //        text = value;
        //    }
        //}

        protected override ActivityExecutionStatus Execute(ActivityExecutionContext executionContext)
        {
            //return base.Execute(executionContext);
            Console.WriteLine(Text);
            return ActivityExecutionStatus.Closed;
        }
    }

    [Serializable]
    public class ReadLine : Activity
    {
        //public static readonly DependencyProperty TextProperty =
        //    DependencyProperty.Register("Text",
        //    typeof(string), typeof(WriteLine));

        //public string Text
        //{
        //    get
        //    {
        //        return (string)GetValue(TextProperty);
        //    }
        //    set
        //    {
        //        SetValue(TextProperty, value);
        //    }
        //}

        private string text;
        public string Text
        {
            get
            {
                return text;
            }
        }

        protected override ActivityExecutionStatus Execute(ActivityExecutionContext executionContext)
        {
            //return base.Execute(executionContext);
            Console.WriteLine("ReadLine Execute");

            WorkflowQueuingService qService = 
                executionContext.GetService<WorkflowQueuingService>();

            WorkflowQueue queue =
                qService.CreateWorkflowQueue(this.Name, true);
            queue.QueueItemAvailable += this.ContinueAt;

            return ActivityExecutionStatus.Executing;
        }

        void ContinueAt(object sender, QueueEventArgs e)
        {
            Console.WriteLine("ReadLine ContinueAt");

            ActivityExecutionContext aec =
                sender as ActivityExecutionContext;

            WorkflowQueuingService qService =
                aec.GetService<WorkflowQueuingService>();

            WorkflowQueue queue = qService.GetWorkflowQueue(this.Name);
            text = (string)queue.Dequeue();

            qService.DeleteWorkflowQueue(this.Name);
            aec.CloseActivity();
        }
    }

}
